home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / php / pear / File.php < prev    next >
PHP Script  |  2004-03-24  |  17KB  |  537 lines

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2003 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.0 of the PHP license,       |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Richard Heyes <richard@php.net>                             |
  17. // |          Tal Peer <tal@php.net>                                      |
  18. // +----------------------------------------------------------------------+
  19.  
  20.  
  21. /*
  22. * Example 1:
  23. * $stdin = File::readAll('php://stdin');
  24. *
  25. * Example 2:
  26. * while ($data = File::read('/blaat/bar')) {
  27. *     // Code...
  28. * }
  29. */
  30.  
  31. require_once('PEAR.php');
  32.  
  33. /**
  34. * The default number of bytes for reading
  35. * @const FILE_DEFAULT_READSIZE
  36. */
  37. define('FILE_DEFAULT_READSIZE', 1024, true);
  38.  
  39. /**
  40. * Mode to use for reading from files
  41. * @const FILE_MODE_READ
  42. */
  43. define('FILE_MODE_READ',   'rb', true);
  44.  
  45. /**
  46. * Mode to use for truncating files, then writing
  47. * @const FILE_MODE_WRITE
  48. */
  49. define('FILE_MODE_WRITE',  'wb', true);
  50.  
  51. /**
  52. * Mode to use for appending to files
  53. * @const FILE_MODE_APPEND
  54. */
  55. define('FILE_MODE_APPEND', 'ab', true);
  56.  
  57. /**
  58. * Use this when a shared (read) lock is required
  59. * @const FILE_LOCK_SHARED
  60. */
  61. define('FILE_LOCK_SHARED',    LOCK_SH, true);
  62.  
  63. /**
  64. * Use this when an exclusive (write) lock is required
  65. * @const FILE_LOCK_EXCLUSIVE
  66. */
  67. define('FILE_LOCK_EXCLUSIVE', LOCK_EX, true);
  68.  
  69. /**
  70. * Class for handling files
  71. *
  72. * A class with common functions for writing,
  73. * reading and handling files and directories
  74. *
  75. *
  76. * @author  Richard Heyes <richard@php.net>
  77. * @author  Tal Peer <tal@php.net>
  78. * @access  public
  79. * @version 0.9
  80. * @package File
  81. */
  82. class File extends PEAR
  83. {
  84.     /**
  85.     * Destructor
  86.     *
  87.     * Unlocks any locked file pointers and closes all filepointers
  88.     * @access private
  89.     */
  90.     function _File()
  91.     {
  92.         $locks = &PEAR::getStaticProperty('File', 'locks');
  93.         $filePointers = &PEAR::getStaticProperty('File', 'filePointers');
  94.  
  95.         for ($i = 0; $i < count($locks); $i++) {
  96.             flock($this->locks[$i], LOCK_UN);
  97.         }
  98.  
  99.         if (!empty($filePointers)) {
  100.             foreach ($filePointers as $fname => $value) {
  101.                 foreach ($value as $mode => $value) {
  102.                     @fclose($filePointers[$fname][$mode]);
  103.                 }
  104.             }
  105.         }
  106.     }
  107.  
  108.     /**
  109.     * Handles file pointers. If a file pointer needs to be opened,
  110.     * it will be. If it already exists (based on filename and mode)
  111.     * then the existing one will be returned.
  112.     *
  113.     * @access private
  114.     * @param  string  $filename Filename to be used
  115.     * @param  string  $mode     Mode to open the file in
  116.     * @param  mixed   $lock     Type of lock to use
  117.     * @return mixed             PEAR_Error on error and file pointer resource on success
  118.     */
  119.     function &_getFilePointer($filename, $mode, $lock = false)
  120.     {
  121.         $filePointers = &PEAR::getStaticProperty('File', 'filePointers');
  122.  
  123.         // Need to open first...
  124.         if (!isset($filePointers[$filename][$mode]) OR !is_resource($filePointers[$filename][$mode])) {
  125.  
  126.             // Check it exists
  127.             if (FILE_MODE_READ == $mode AND !preg_match('/^(http|https|ftp|php):\/\//i', $filename) AND !file_exists($filename)) {
  128.                 return PEAR::raiseError('File does not exist: ' . $filename);
  129.  
  130.             // Writeable?
  131.             } elseif ( (FILE_MODE_WRITE == $mode OR FILE_MODE_APPEND == $mode)
  132.                         AND !file_exists($filename)
  133.                         AND !is_writeable(dirname($filename))) {
  134.  
  135.                 return PEAR::raiseError('Could not create file: ' . $filename);
  136.  
  137.             } elseif ( (FILE_MODE_WRITE == $mode OR FILE_MODE_APPEND == $mode)
  138.                         AND !is_writeable(dirname($filename))) {
  139.  
  140.                 return PEAR::raiseError('File is not writeable: ' . $filename);
  141.             }
  142.  
  143.             $filePointers[$filename][$mode] = @fopen($filename, $mode);
  144.             if (false === $filePointers[$filename][$mode]) {
  145.                 return PEAR::raiseError('Failed to open file: ' . $filename);
  146.             }
  147.         }
  148.  
  149.         // Lock it?
  150.         if ($lock) {
  151.             $locks = &PEAR::getStaticProperty('File', 'locks');
  152.             if (flock($filePointers[$filename][$mode], $lock)) {
  153.                 $this->locks[] = &$filePointers[$filename][$mode];
  154.             }
  155.         }
  156.         return $filePointers[$filename][$mode];
  157.     }
  158.  
  159.     /**
  160.     * Reads an entire file and returns it.
  161.     *
  162.     * @access public
  163.     * @param  string $filename Name of file to read from
  164.     * @param  mixed  $lock     Type of lock to use
  165.     * @return mixed            PEAR_Error if an error has occured or a string with the contents of the the file
  166.     */
  167.     function readAll($filename, $lock = false)
  168.     {
  169.         $file = '';
  170.         while (($tmp = File::read($filename, FILE_DEFAULT_READSIZE, $lock)) !== FALSE) {
  171.             if (PEAR::isError($tmp)) {
  172.                 return $tmp;
  173.             }
  174.             $file .= $tmp;
  175.         }
  176.  
  177.         return $file;
  178.     }
  179.  
  180.     /**
  181.     * Returns a specified number of bytes of a file. Defaults to 1024.
  182.     *
  183.     * @access public
  184.     * @param  string  $filename Name of file to read from
  185.     * @param  integer $size     Bytes to read
  186.     * @param  mixed   $lock     Type of lock to use
  187.     * @return mixed             PEAR_Error on error or a string which contains the data read
  188.     *                           Will also return false upon EOF
  189.     */
  190.     function read($filename, $size = FILE_DEFAULT_READSIZE, $lock = false)
  191.     {
  192.         static $filePointers; // Used to prevent unnecessary calls to _getFilePointer()
  193.  
  194.         if (0 == $size) {
  195.             return File::readAll($filename);
  196.         }
  197.  
  198.         if (!isset($filePointers[$filename]) OR !is_resource($filePointers[$filename])) {
  199.             if (PEAR::isError($fp = &File::_getFilePointer($filename, FILE_MODE_READ, $lock))) {
  200.                 return $fp;
  201.             }
  202.  
  203.             $filePointers[$filename] = &$fp;
  204.  
  205.         } else {
  206.             $fp = &$filePointers[$filename];
  207.         }
  208.  
  209.         return !feof($fp) ? fread($fp, $size) : false;
  210.     }
  211.  
  212.     /**
  213.     * Writes the given data to the given filename. Defaults to no lock, append mode.
  214.     *
  215.     * @access public
  216.     * @param  string $filename Name of file to write to
  217.     * @param  string $data     Data to write to file
  218.     * @param  string $mode     Mode to open file in
  219.     * @param  mixed  $lock     Type of lock to use
  220.     * @return mixed             PEAR_Error on error or number of bytes written to file.
  221.     */
  222.     function write($filename, $data, $mode = FILE_MODE_APPEND, $lock = false)
  223.     {
  224.         if (!PEAR::isError($fp = &File::_getFilePointer($filename, $mode, $lock))) {
  225.             if (($bytes = fwrite($fp, $data, strlen($data))) == -1) {
  226.                 return PEAR::raiseError(sprintf('fwrite() call failed to write data: "%s" to file: "%s"', $data, $filename));
  227.             } else {
  228.                 return $bytes;
  229.             }
  230.         }
  231.  
  232.         return $fp;
  233.     }
  234.  
  235.     /**
  236.     * Reads and returns a single character from given filename
  237.     *
  238.     * @access public
  239.     * @param  string $filename Name of file to read from
  240.     * @param  mixed  $lock     Type of lock to use
  241.     * @return mixed            PEAR_Error on error or one character of the specified file
  242.     */
  243.     function readChar($filename, $lock = false)
  244.     {
  245.         return File::read($filename, 1, $lock);
  246.     }
  247.  
  248.     /**
  249.     * Writes a single character to a file
  250.     *
  251.     * @access public
  252.     * @param  string $filename Name of file to write to
  253.     * @param  string $char     Character to write
  254.     * @param  string $mode     Mode to use when writing
  255.     * @param  mixed  $lock     Type of lock to use
  256.     * @return mixed            PEAR_Error on error, or 1 on success
  257.     */
  258.     function writeChar($filename, $char, $mode = FILE_MODE_APPEND, $lock = false)
  259.     {
  260.         if (!PEAR::isError($fp = &File::_getFilePointer($filename, $mode, $lock))) {
  261.             if (fwrite($fp, $char, 1) == -1) {
  262.                 return PEAR::raiseError(sprintf('fwrite() call failed to write data: "%s" to file: "%s"', $data, $filename));
  263.             } else {
  264.                 return 1;
  265.             }
  266.         }
  267.  
  268.         return $fp;
  269.     }
  270.  
  271.     /**
  272.     * Returns a line of the file
  273.     *
  274.     * @access public
  275.     * @param  string  $filename Name of file to read from
  276.     * @param  boolean $lock     Type of lock to use
  277.     * @return mixed             PEAR_Error on error or a string containing the line read from file
  278.     */
  279.     function readLine($filename, $lock = false)
  280.     {
  281.         static $filePointers; // Used to prevent unnecessary calls to _getFilePointer()
  282.  
  283.         if (!isset($filePointers[$filename]) OR !is_resource($filePointers[$filename])) {
  284.             if (PEAR::isError($fp = &File::_getFilePointer($filename, FILE_MODE_READ, $lock))) {
  285.                 return $fp;
  286.             }
  287.  
  288.             $filePointers[$filename] = &$fp;
  289.  
  290.         } else {
  291.             $fp = &$filePointers[$filename];
  292.         }
  293.  
  294.         if (feof($fp)) {
  295.             return false;
  296.         }
  297.  
  298.         $fileString = '';
  299.         while (($fileChar = fgetc($fp)) != "\n" AND !feof($fp)) {
  300.             $fileString .= $fileChar;
  301.         }
  302.  
  303.         return substr($fileString, -1) == "\r" ? substr($fileString, 0, -1) : $fileString;
  304.     }
  305.  
  306.     /**
  307.     * Writes a single line, appending a LF (by default)
  308.     *
  309.     * @access public
  310.     * @param  string $filename Name of file to write to
  311.     * @param  string $line     Line of data to be written to file
  312.     * @param  string $mode     Write mode, can be either FILE_MODE_WRITE or FILE_MODE_APPEND
  313.     * @param  string $crlf     The CRLF your system is using. UNIX = \n Windows = \r\n Mac = \r
  314.     * @param  mixed  $lock     Type of lock to use
  315.     * @return mixed            PEAR_Error on error or number of bytes written to file (including appended crlf)
  316.     */
  317.     function writeLine($filename, $line, $mode = FILE_MODE_APPEND, $crlf = "\n", $lock = false)
  318.     {
  319.         if(!PEAR::isError($fp = &File::_getFilePointer($filename, $mode, $lock))){
  320.             if (($bytes = fwrite($fp, $line . $crlf)) == -1) {
  321.                 return PEAR::raiseError(sprintf('fwrite() call failed to write data: "%s" to file: "%s"', $data, $filename));
  322.             } else {
  323.                 return $bytes;
  324.             }
  325.         }
  326.  
  327.         return $fp;
  328.     }
  329.  
  330.     /**
  331.     * This rewinds a filepointer to the start of a file
  332.     *
  333.     * @access public
  334.     * @param  string $filename The filename
  335.     * @param  string $mode     Mode the file was opened in
  336.     * @return mixed            PEAR Error on error, true on success
  337.     */
  338.     function rewind($filename, $mode)
  339.     {
  340.         if (!PEAR::isError($fp = &File::_getFilePointer($filename, $mode))) {
  341.             return rewind($fp) ? true : PEAR::raiseError('Failed to rewind file: ' . $filename);
  342.         }
  343.  
  344.         return $fp;
  345.     }
  346.  
  347.     /**
  348.     * This closes an open file pointer
  349.     *
  350.     * @access public
  351.     * @param  string $filename The filename that was opened
  352.     * @param  string $mode     Mode the file was opened in
  353.     * @return mixed            PEAR Error on error, true otherwise
  354.     */
  355.     function close($filename, $mode)
  356.     {
  357.         if (!PEAR::isError($fp = &File::_getFilePointer($filename, $mode))) {
  358.             $filePointers = &PEAR::getStaticProperty('File', 'filePointers');
  359.             unset($filePointers[$filename][$mode]);
  360.             return fclose($fp) ? true : PEAR::raiseError('Failed to close file: ' . $filename);
  361.         }
  362.  
  363.         return $fp;
  364.     }
  365.  
  366.     /**
  367.     * This unlocks a locked file pointer.
  368.     *
  369.     * @access public
  370.     * @param  string $filename The filename that was opened
  371.     * @param  string $mode     Mode the file was opened in
  372.     * @return mixed            PEAR Error on error, true otherwise
  373.     */
  374.     function unlock($filename, $mode)
  375.     {
  376.         if (!PEAR::isError($fp = &FILE::_getFilePointer($filename, $mode))) {
  377.             return flock($fp, LOCK_UN) ? true : PEAR::raiseError('Failed to unlock file: ' . $filename);
  378.         }
  379.  
  380.         return $fp;
  381.     }
  382.  
  383.     /**
  384.     * Returns a string path built from the array $pathParts. Where a join occurs
  385.     * multiple separators are removed. Joins using the optional separator, defaulting
  386.     * to the PHP DIRECTORY_SEPARATOR constant.
  387.     *
  388.     * @access public
  389.     * @param  array  $parts     Array containing the parts to be joined
  390.     * @param  string $separator The system directory seperator
  391.     */
  392.     function buildPath($parts, $separator = DIRECTORY_SEPARATOR)
  393.     {
  394.         for ($i = 0; $i < count($parts); $i++) {
  395.             if (0 == $i) {
  396.                 $parts[$i] = File::stripTrailingSeparators($parts[$i], $separator);
  397.  
  398.             } elseif(count($parts) - 1 == $i) {
  399.                 $parts[$i] = File::stripLeadingSeparators($parts[$i], $separator);
  400.  
  401.             } else {
  402.                 $parts[$i] = File::stripTrailingSeparators($parts[$i], $separator);
  403.                 $parts[$i] = File::stripLeadingSeparators($parts[$i], $separator);
  404.             }
  405.         }
  406.  
  407.         return implode($separator, $parts);
  408.     }
  409.  
  410.     /**
  411.     * Strips trailing separators from the given path
  412.     *
  413.     * @access public
  414.     * @param  string $path      Path to use
  415.     * @param  string $separator Separator to look for
  416.     * @return string            Resulting path
  417.     */
  418.     function stripTrailingSeparators($path, $separator = DIRECTORY_SEPARATOR)
  419.     {
  420.         while (substr($path, -1) == $separator) {
  421.             $path = substr($path, 0, -1);
  422.         }
  423.  
  424.         return $path;
  425.     }
  426.  
  427.     /**
  428.     * Strips leading separators from the given path
  429.     *
  430.     * @access public
  431.     * @param  string $path      Path to use
  432.     * @param  string $separator Separator to look for
  433.     * @return string            Resulting path
  434.     */
  435.     function stripLeadingSeparators($path, $separator = DIRECTORY_SEPARATOR)
  436.     {
  437.         while (substr($path, 0, 1) == $separator) {
  438.             $path = substr($path, 1);
  439.         }
  440.  
  441.         return $path;
  442.     }
  443.  
  444.     /**
  445.     * Returns a path without leading / or C:\. If this is not
  446.     * present the path is returned as is.
  447.     *
  448.     * @access public
  449.     * @param  string $path The path to be processed
  450.     * @return string       The processed path or the path as is
  451.     */
  452.     function skipRoot($path)
  453.     {
  454.         if (File::isAbsolute($path)) {
  455.             if (DIRECTORY_SEPARATOR == "/") {
  456.                 return substr($path,1);
  457.  
  458.             } elseif(DIRECTORY_SEPARATOR == "\\") {
  459.                 return substr($path, 3);
  460.             }
  461.         } else {
  462.             return $path;
  463.         }
  464.     }
  465.  
  466.     /**
  467.     * Returns the temp directory according to either the TMP, TMPDIR, or TEMP env
  468.     * variables. If these are not set it will also check for the existence of
  469.     * /tmp, %WINDIR%\temp
  470.     *
  471.     * @access public
  472.     * @return string The system tmp directory
  473.     */
  474.     function getTempDir()
  475.     {
  476.         if (OS_WINDOWS){
  477.             if (isset($_ENV['TEMP'])) {
  478.                 return $_ENV['TEMP'];
  479.             }
  480.             if (isset($_ENV['TMP'])) {
  481.                 return $_ENV['TMP'];
  482.             }
  483.             if (isset($_ENV['windir'])) {
  484.                 return $_ENV['windir'] . '\temp';
  485.             }
  486.             return $_ENV['SystemRoot'] . '\temp';
  487.         }
  488.         if (isset($_ENV['TMPDIR'])) {
  489.             return $_ENV['TMPDIR'];
  490.         }
  491.         return '/tmp';
  492.     }
  493.  
  494.     /**
  495.     * Returns a temporary filename using tempnam() and the above getTmpDir() function.
  496.     *
  497.     * @access public
  498.     * @param  string $dirname Optional directory name for the tmp file
  499.     * @return string          Filename and path of the tmp file
  500.     */
  501.     function getTempFile($dirname = NULL)
  502.     {
  503.         if (is_null($dirname)) {
  504.             $dirname = File::getTempDir();
  505.         }
  506.         return tempnam($dirname, 'temp.');
  507.     }
  508.  
  509.     /**
  510.     * Returns boolean based on whether given path is absolute or not.
  511.     *
  512.     * @access public
  513.     * @param  string  $path Given path
  514.     * @return boolean       True if the path is absolute, false if it is not
  515.     */
  516.     function isAbsolute($path)
  517.     {
  518.         if (preg_match("/\.\./", $path)) {
  519.             return false;
  520.         }
  521.  
  522.         if (DIRECTORY_SEPARATOR == '/' AND (substr($path, 0, 1) == '/' OR substr($path, 0, 1) == '~')) {
  523.             return true;
  524.  
  525.         } elseif(DIRECTORY_SEPARATOR == '\\' AND preg_match('/^[a-z]:\\\/i', $path)) {
  526.             return true;
  527.  
  528.         }
  529.  
  530.         return false;
  531.     }
  532. }
  533.  
  534. PEAR::registerShutdownFunc(array('File', '_File'));
  535.  
  536. ?>
  537.